﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using System.Linq;
using System.Xml.Linq;
using WebApplication1.chat;
using WebApplication1.Model;
using WebApplication1.Service;

namespace WebApplication1.Controllers
{
    [ApiController]
    [Route("/api/v1")]
    public class HomeController : ControllerBase
    {
        public HomeController(IHubContext<VideoHub, INotityVideo> hubClients,ChatService chartService)
        {
            HubClients = hubClients;
            ChartService = chartService;
        }
        //public static Dictionary<String, StreamData[]> SingleData = new Dictionary<String, StreamData[]>();

        public IHubContext<VideoHub, INotityVideo> HubClients { get; }
        public ChatService ChartService { get; }

        [HttpPost("streams")]
        public async Task<int> streams([FromBody] StreamData data)
        {
            var allStream = ChartService.GetAllStream();
            if (data.action == "on_publish")
            {
                //推流的时候判断是否存在同名的流，如果存在就先删除，在添加
                if (allStream.Any(s => s.stream == data.stream))
                {
                    allStream.RemoveAt(allStream.FindIndex(s => s.stream == data.stream));
                    ChartService.AddStream(data);
                }
                else
                {
                    ChartService.AddStream(data);
                }
                if (data.app.Contains("single"))//判断是否是单聊
                {
                    var replacesingle = data.app.Replace("single", "");
                    var name = replacesingle.Split("And");//单聊拿到两个人的名字
                    var allUser = ChartService.GetAllUser();
                    if (allUser.Any(s => s.Name == name[0]) && allUser.Any(s => s.Name == name[1]))//判断两个人是否在在线列表中
                    {
                        var user = allUser.FirstOrDefault(s => s.Name == name[1]);//拿到第二个人的
                        var users = allUser.FirstOrDefault(s => s.Name == name[0]);//拿到第一个人
                        var allSingleChat = ChartService.GetSingleChat();
                        if (allSingleChat.ContainsKey(data.app))
                        {
                            var datas = allSingleChat[data.app];
                            datas[1] = data;

                            await HubClients.Clients.Clients(user.Id, users.Id).Notity(datas.ToList());
                        }
                        else
                        {
                            var resData = new StreamData[2];
                            resData[0] = data;
                            resData[1] = null;//因为单聊的时候第一个人的流已经推了，第二个人的需要等进入到聊天页面后才可以推，就是上面的那个判断是否存在data.app
                            //SingleData.Add(data.app, resData);
                            ChartService.AddSingleChat(data.app, resData);//添加单聊的两个人的数据
                            await HubClients.Clients.Clients(users.Id).Notity(new List<StreamData> { data});
                            await HubClients.Clients.Client(user.Id).SingleChat(name[0], name[1]);//通知单聊的两个人进入单聊页面
                        }
                    }
                }
                else if (data.app.Contains("group"))
                {
                    var groupName = data.app.Replace("group", "");
                    var allGroup = ChartService.GetGroupChat();//获取群聊的数据
                    if (allGroup.TryGetValue(groupName, out GroupModel va))//根据群聊名称拿到群聊的model
                    {
                        va.RequestDatas.Add(data);
                        await HubClients.Clients.Clients(va.AllUsers.Select(s => s.Id)).Notity(va.RequestDatas);//通知群聊的所有用户 有人进来并拉取进来的人的摄像头的流
                    }
                }
                else if (data.app.Contains("share"))
                {
                    var allShare = ChartService.GetShare();//获取群聊的数据
                    var key = data.stream;
                    if (data.stream.Contains("Audio"))
                    {
                        key= data.stream.Replace("Audio","");
                    }
                    if (allShare.TryGetValue(key, out GroupModel va))//根据群聊名称拿到群聊的model
                    {
                        va.RequestDatas.Add(data);
                        await HubClients.Clients.Clients(va.AllUsers.Select(s => s.Id)).Notity(va.RequestDatas);//通知群聊的所有用户 有人进来并拉取进来的人的摄像头的流
                    }
                }
            }
            else
            {
                if (allStream.Any(s => s.client_id == data.client_id))
                {
                    var dat = allStream.FirstOrDefault(s => s.client_id == data.client_id);
                    allStream.Remove(dat);
                }
                //移除流从所有的流数据中
            }
            allStream = allStream.Distinct().ToList();
            return 0;
        }
        [HttpPost("sessions")]
        public int sessions()
        {
            return 0;
        }
        [HttpGet("data")]
        public List<StreamData> data()
        {
            return ChartService.GetAllStream();//获取所有的流
        }
        [HttpGet("GetUser")]
        public List<UserModel> GetUser()
        {
            return ChartService.GetAllUser();//获取所有的在线用户
        }
        [HttpPost("AddGroup")]
        public async Task AddGroup(GroupModel groupModel)
        {
            if (ChartService.GetGroupChat().ContainsKey(groupModel.Name))//判断是否存在同名从group
            {
                var group = ChartService.GetGroupChat()[groupModel.Name];
                var user = ChartService.GetAllUser().FirstOrDefault(s => s.Id == groupModel.Id);
                if (user != null)
                {
                    group.AllUsers.Add(user);
                    await HubClients.Groups.AddToGroupAsync(groupModel.Id, groupModel.Name);  //如果已经存在了一个group就给这个group增加一个用户
                }
            }
            else
            {
                var user = ChartService.GetAllUser().FirstOrDefault(s => s.Id == groupModel.Id);//如果不存在group就新增一个group，将当前用户添加到groups的数据中，
                if (user != null)
                {
                    groupModel.AllUsers.Add(user);
                    ChartService.AddGroupChat(groupModel.Name, groupModel);
                    await HubClients.Groups.AddToGroupAsync(groupModel.Id, groupModel.Name);
                }
            }
            await HubClients.Clients.All.GroupChange(ChartService.GetGroupChat().Values.ToList());//通知ui有新增的群组
        }
        [HttpGet("GetGroup")]
        public List<GroupModel> GetGroup()
        {
            return ChartService.GetGroupChat().Values.ToList();//获取所有群组的接口
        }
        [HttpGet("GetGroupByName")]
        public GroupModel GetGroupByName([FromQuery] string Name)
        {
            var groupName = Name.Split("Time");

            return ChartService.GetGroupChat().Values.Where(s=>s.Name== groupName[0]).FirstOrDefault();//获取所有群组的接口
        }
        [HttpGet("RemoveGroup")]
        public async Task RemoveGroup([FromQuery] string Name)
        {
            var group = ChartService.GetGroupChat()[Name];//判断当前name群组是否在群组列表中
            if (group != null)
            {
                group.AllUsers.ForEach(async s =>
                {
                    await HubClients.Groups.RemoveFromGroupAsync(s.Id, Name);//如果存在这个群组，就吧所有用户从这个群组中移除。
                });
            }
            ChartService.GetGroupChat().Remove(Name);//并且群组列表中移除这个群主

            await HubClients.Clients.All.GroupChange(ChartService.GetGroupChat().Values.ToList());//通知ui有移除的群组
        }
        [HttpGet("RemoveUserFromGroup")]
        public async Task RemoveUserFromGroup([FromQuery] string Id, [FromQuery] string GroupName)//从群组移除某个用户，用户从群组中退出之后更新ui和群组的用户信息
        {
            if (ChartService.GetGroupChat().ContainsKey(GroupName))//存在群组
            {
                var group = ChartService.GetGroupChat()[GroupName];//拿到群组信息
                if (group != null)
                {
                    group.AllUsers.ForEach(async s =>
                    {
                        if (s.Id == Id)
                        {
                            await HubClients.Groups.RemoveFromGroupAsync(s.Id, GroupName);//如果存在这个群组，就吧退出的这个用户从这个群组中移除。

                        }
                    });
                    if (group.AllUsers.Any(s => s.Id == Id))
                    {
                        var model = group.AllUsers.FirstOrDefault(s => s.Id == Id);//找到当前群组的这个用户
                        var RequestData = group.RequestDatas.FirstOrDefault(s => s.stream.Contains(model.Name));//找到这个用户推送的流
                        if (RequestData != null)
                        {
                            group.RequestDatas.Remove(RequestData);//移除这个推送的流
                        }
                        group.AllUsers.Remove(model);//并且从群组列表中移除这个用户
                    }

                    if (group.AllUsers.Count == 0)
                    {
                        ChartService.GetGroupChat().Remove(GroupName);//如果群组没人了，就移除这个群组
                    }
                    await HubClients.Clients.All.GroupChange(ChartService.GetGroupChat().Values.ToList());//通知群组的更改事件
                    await HubClients.Clients.Clients(group.AllUsers.Select(s => s.Id)).Notity(group.RequestDatas);//通知群聊页面 移除这个退出的用户的流
                }

            }

        }
        [HttpGet("RemoveSingleChat")]
        public async Task RemoveSingleChat([FromQuery] string Name)
        {
            var allSingleChat = ChartService.GetSingleChat();
            if (allSingleChat.Keys.Any(s => s.Contains(Name)))
            {
                var keys = allSingleChat.Keys.FirstOrDefault(s => s.Contains(Name));//找到这个单聊的数据
                var datas = allSingleChat[keys];
                var data = datas.FirstOrDefault(s =>s!=null&& s.stream.Split("Time")[0] == Name);//找到单聊的流数据
                if (data != null)
                {
                    var name = keys.Replace("single", "");//根据single分割 找到单聊的两个人的名字
                    var names = name.Split("And");
                    var notityName = names.FirstOrDefault(s => s != Name);//找到单聊中不等于这个名字的另一个人。
                    var user = ChartService.GetAllUser().FirstOrDefault(s => s.Name == notityName);//找到是否存在这个用户
                    if (user != null)
                    {
                        await HubClients.Clients.Client(user.Id).CloseChat();//通知这个用户退出聊天
                        allSingleChat.Remove(keys);//移除这个单聊
                    }
                }
                else
                {
                    data = datas.FirstOrDefault(s=>s!=null);
                    var name = keys.Replace("single", "");//根据single分割 找到单聊的两个人的名字
                    var names = name.Split("And");
                    var notityName = names.FirstOrDefault(s => s != Name);//找到单聊中不等于这个名字的另一个人。
                    var user = ChartService.GetAllUser().FirstOrDefault(s => s.Name == notityName);//找到是否存在这个用户
                    if (user != null)
                    {
                        await HubClients.Clients.Client(user.Id).CloseChat();//通知这个用户退出聊天
                        allSingleChat.Remove(keys);//移除这个单聊
                    }
                }
            }
        }

        [HttpGet("IsSingleChat")]
        public bool IsSingleChat([FromQuery] string Name)
        {
            //判断聊天的用户是否正在单聊中
            var allSingleChat = ChartService.GetSingleChat();
            if (allSingleChat.Keys.Any(s => s.Contains(Name)))
            {
               return true;
            }
            return false;
        }
        /// <summary>
        /// 新增屏幕共享
        /// </summary>
        /// <param name="groupModel"></param>
        /// <returns></returns>
        [HttpPost("AddShare")]
        public async Task AddShare(GroupModel groupModel)
        {
            if (ChartService.GetShare().ContainsKey(groupModel.Name))//判断是否存在同名从group
            {
                var group = ChartService.GetShare()[groupModel.Name];
                var user = ChartService.GetAllUser().FirstOrDefault(s => s.Id == groupModel.Id);
                if (user != null)
                {
                    group.AllUsers.Add(user);
                    await HubClients.Groups.AddToGroupAsync(groupModel.Id, groupModel.Name);  //如果已经存在了一个group就给这个group增加一个用户
                    await HubClients.Clients.Clients(group.AllUsers.Select(s=>s.Id)).ShareInsertUser(group);
                }
            }
            else
            {
                var user = ChartService.GetAllUser().FirstOrDefault(s => s.Id == groupModel.Id);//如果不存在group就新增一个group，将当前用户添加到groups的数据中，
                if (user != null)
                {
                    groupModel.AllUsers.Add(user);
                    ChartService.AddShare(groupModel.Name, groupModel);
                    await HubClients.Groups.AddToGroupAsync(groupModel.Id, groupModel.Name);
                    await HubClients.Clients.Client(user.Id).ShareInsertUser(groupModel) ;
                }
            }
            await HubClients.Clients.All.ShareChange(ChartService.GetShare().Values.ToList());//通知ui有新增的屏幕共享
        }
        /// <summary>
        /// 获取所有共享列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("GetShare")]
        public List<GroupModel> GetShare()
        {
            return ChartService.GetShare().Values.ToList();//获取所有群组的接口
        }
        /// <summary>
        /// 从屏幕共享移除某个用户
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="GroupName"></param>
        /// <returns></returns>
        [HttpGet("RemoveUserFromShare")]
        public async Task RemoveUserFromShare([FromQuery] string Id, [FromQuery] string GroupName)//从群组移除某个用户，用户从群组中退出之后更新ui和群组的用户信息
        {
            if (ChartService.GetShare().ContainsKey(GroupName))//存在群组
            {
                var group = ChartService.GetShare()[GroupName];//拿到群组信息
                if (group != null)
                {
                    group.AllUsers.ForEach(async s =>
                    {
                        if (s.Id == Id)
                        {
                            await HubClients.Groups.RemoveFromGroupAsync(s.Id, GroupName);//如果存在这个群组，就吧退出的这个用户从这个群组中移除。

                        }
                    });
                    if (group.AllUsers.Any(s => s.Id == Id))
                    {
                        var model = group.AllUsers.FirstOrDefault(s => s.Id == Id);//找到当前群组的这个用户
                        var RequestData = group.RequestDatas.FirstOrDefault(s => s.app.Contains(model.Name));//找到这个用户推送的流
                        if (RequestData != null)
                        {
                            group.RequestDatas.Remove(RequestData);//移除这个推送的流
                        }
                        group.AllUsers.Remove(model);//并且从群组列表中移除这个用户
                    }

                    if (group.AllUsers.Count == 0)
                    {
                        ChartService.GetShare().Remove(GroupName);//如果群组没人了，就移除这个群组
                    }
                    await HubClients.Clients.All.ShareChange(ChartService.GetShare().Values.ToList());//通知群组的更改事件
                    await HubClients.Clients.Clients(group.AllUsers.Select(s => s.Id)).Notity(group.RequestDatas);//通知群聊页面 移除这个退出的用户的流
                    await HubClients.Clients.Clients(group.AllUsers.Select(s => s.Id)).ShareInsertUser(group);
                }

            }

        }
        /// <summary>
        /// 删除共享
        /// </summary>
        /// <param name="Name"></param>
        /// <returns></returns>
        [HttpGet("RemoveShare")]
        public async Task RemoveShare([FromQuery] string Name)
        {
            var group = ChartService.GetShare()[Name];//判断当前name群组是否在群组列表中
            if (group != null)
            {
                group.AllUsers.ForEach(async s =>
                {
                    await HubClients.Groups.RemoveFromGroupAsync(s.Id, Name);//如果存在这个群组，就吧所有用户从这个群组中移除。
                });
            }
            ChartService.GetShare().Remove(Name);//并且群组列表中移除这个群主

            await HubClients.Clients.All.ShareChange(ChartService.GetShare().Values.ToList());//通知ui有移除的群组
        }
        /// <summary>
        /// 获取共享的信息
        /// </summary>
        /// <param name="Name"></param>
        /// <returns></returns>
        [HttpGet("GetShareUser")]
        public GroupModel GetShareUser([FromQuery] string Name)
        {
            var group = ChartService.GetShare()[Name];//判断当前name群组是否在群组列表中
            if (group != null)
            {
                return group;
            }
            return null;
        }
        [HttpGet("StopShare")]
        public async Task StopShare([FromQuery] string Name)
        {
            var groupName = Name.Split("Time");
            var group = ChartService.GetShare()[groupName[0]];//判断当前name群组是否在群组列表中
            if (group != null)
            {
                group.RequestDatas= group.RequestDatas.Where(s=>s.stream.Contains("Audio")).ToList();
               await HubClients.Clients.Clients(group.AllUsers.Select(s => s.Id)).StopShare(group);
                await HubClients.Clients.Clients(group.AllUsers.Select(s => s.Id)).Notity(group.RequestDatas);
            }
        }
        /// <summary>
        /// 获取单聊的流信息
        /// </summary>
        /// <param name="Name"></param>
        /// <returns></returns>
        [HttpGet("GetSingleChat")]
        public StreamData[] GetSingleChat([FromQuery] string Name)
        {

            var singleName = Name.Split("Time");
            var key= ChartService.GetSingleChat().Keys.FirstOrDefault(s => s.Contains(singleName[0]));
            if (key != null)
            {
                var model = ChartService.GetSingleChat()[key];
                return model;
            }
            return null;
        }
        /// <summary>
        /// 没有摄像头或者耳麦的通知单聊
        /// </summary>
        /// <param name="Name"></param>
        /// <returns></returns>
        [HttpGet("NoVideoAndAudioNotity")]
        public async Task NoVideoAndAudioNotity([FromQuery] string Name)
        {
            var key = ChartService.GetSingleChat().Keys.FirstOrDefault(s => s.Contains(Name));
            if (key != null)
            {
                var model = ChartService.GetSingleChat()[key];
                var names = key.Replace("single", "");//根据single分割 找到单聊的两个人的名字
                var Allname = names.Split("And");
                var notityName = Allname.FirstOrDefault(s => s != Name);
                var user = ChartService.GetAllUser().FirstOrDefault(s => s.Name == notityName);//找到是否存在这个用户
                if (user != null)
                {
                    await HubClients.Clients.Client(user.Id).Notity(model.Where(s=>s!=null).ToList());//通知这个用户退出聊天
                }
            }
        }
        /// <summary>
        /// 拒绝或者接受视频通话的通知 single111And222
        /// </summary>
        /// <param name="Name"></param>
        /// <returns></returns>
        [HttpGet("NotitySingleChat")]
        public async Task NotitySingleChat([FromQuery] string FromName, [FromQuery] string ToName, [FromQuery] string State)
        {
            var allSingleChat = ChartService.GetSingleChat();
            if (allSingleChat.ContainsKey("single"+FromName + "And" + ToName))
            {
                var user = ChartService.GetAllUser().FirstOrDefault(s => s.Name == FromName);
                if (user != null)
                {
                    await HubClients.Clients.Client(user.Id).NotityChat(State);
                }
            }
        }
    }
}
